﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.Sql;
using System.Data.SqlClient;
using System.IO;

using System.Collections;
using System.Data.Objects;
using System.Data.Objects.DataClasses;


namespace Inference
{
    public partial class frmProduct : Form
    {
        public frmProduct(bool if_edit, int _prodID, int _slotID, int _frameID)
        {
            IfEdit = if_edit;
            ProdID = _prodID;
            SlotID = _slotID;
            FrameID = _frameID;
            InitializeComponent();
        }

        int ProdID = -1, SlotID = -1, FrameID = -1;
        bool IfEdit = false;
        TaleEntities Tale = new TaleEntities();
        Frames.SlotForm fmsl;
        SqlConnection conn; string ConnectionString = "";

        private void LoadProduct(int prodID)
        {
            dgPremise.Rows.Clear();
            dgConc.Rows.Clear();
            //var prod_facts = (Tale.ViewProductions.Where(v => v.SlotID == SlotDomID).GroupBy(v => v.ProductionID)).OrderBy(v=>v.Type);
            var prod_facts = from p in Tale.ViewProductions where (p.SlotID == SlotID && p.ProductionID == prodID) orderby (p.Type) select p;
            int i = -1, ins_i_p = 0, ins_i_c = 0, fact_in_prod_i = 0;
            foreach (Inference.ViewProductions pr_f in prod_facts)
            {
                if (pr_f.Type == 1)
                {
                    dgPremise.Rows.Add();
                }
                else if (pr_f.Type == 2 || pr_f.Type == 3)
                    dgConc.Rows.Add();

                string str = "";
                var comp_value = Tale.DValues.Where(v => v.ID == pr_f.ValueID).First();
                string comp_slot_name = "";
                List<Slot> chain_slots = CheckIf.GetProductionChain((int)pr_f.Place, (int)pr_f.CompSlotID);//Tale.Slot.Where(v => v.ID == pr_f.CompSlotID).First();
                foreach (Slot sl in chain_slots)
                {
                    comp_slot_name += "'" + sl.Name + "'.";
                }
                comp_slot_name = comp_slot_name.Substring(0, comp_slot_name.Length - 1);

                str = " " + comp_slot_name/*.Name*/ +
                    (pr_f.Negation ? " != " : " = ") + comp_value.Value + " ";
                if (pr_f.Type == 1)
                {
                    dgPremise.Rows[ins_i_p].Cells[0].Value = pr_f.ID;
                    dgPremise.Rows[ins_i_p].Cells[1].Value = str;
                    dgPremise.Rows[ins_i_p].Cells[2].Value = pr_f.CompSlotID;// ff.CompSlotID;
                    dgPremise.Rows[ins_i_p].Cells[3].Value = pr_f.Place;// ff.Place;
                    string valuev = "";
                    // try
                    {
                        Slot slot = Tale.Slot.Where(v => v.ID == pr_f.CompSlotID).First();

                        if (slot.DomainType == null || slot.DomainType == 0)
                        {
                            valuev = Tale.DValues.Where(v => v.ID == pr_f.ValueID).First().Value;
                        }
                        else if (slot.DomainType != null && slot.DomainType > 0)
                        {
                            valuev = Tale.Frame.Where(v => v.ID == pr_f.ValueID).First().Name;
                        }
                    }
                    //catch { }
                    dgPremise.Rows[ins_i_p].Cells[4].Value = valuev; //ff.ValueV;
                    dgPremise.Rows[ins_i_p].Cells[5].Value = pr_f.Negation; //ff.Negation;
                    ins_i_p++;
                }
                else if (pr_f.Type == 2 || pr_f.Type == 3)
                {
                    dgConc.Rows[ins_i_c].Cells[0].Value = pr_f.ID;
                    dgConc.Rows[ins_i_c].Cells[1].Value = str;

                    dgConc.Rows[ins_i_c].Cells[2].Value = pr_f.CompSlotID;// ff.CompSlotID;
                    dgConc.Rows[ins_i_c].Cells[3].Value = pr_f.Place;// ff.Place;
                    string valuev = "";
                    // try
                    {
                        Slot slot = Tale.Slot.Where(v => v.ID == pr_f.CompSlotID).First();

                        if (slot.DomainType == null || slot.DomainType == 0)
                        {
                            valuev = Tale.DValues.Where(v => v.ID == pr_f.ValueID).First().Value;
                        }
                        else if (slot.DomainType != null && slot.DomainType > 0)
                        {
                            valuev = Tale.Frame.Where(v => v.ID == pr_f.ValueID).First().Name;
                        }
                    }
                    //catch { }
                    dgConc.Rows[ins_i_c].Cells[4].Value = valuev; //ff.ValueV;
                    dgConc.Rows[ins_i_c].Cells[5].Value = pr_f.Negation; //ff.Negation;
                    ins_i_c++;
                }
                fact_in_prod_i++;
                //  }
            }
        }

        private void frmProduct_Load(object sender, EventArgs e)
        {
            ConnectionString = "Data Source=.\\SQLEXPRESS;AttachDbFilename=" + Directory.GetCurrentDirectory() +
                "\\Tale.mdf" + ";Integrated Security=True;Connect Timeout=30;User Instance=True";
            conn = new SqlConnection(ConnectionString);
            conn.Open();
            fmsl = (Frames.SlotForm)Application.OpenForms["SlotForm"];
            if (IfEdit)
            {
                this.Text = "Редактирование продукции"; // из слота ";
                LoadProduct(ProdID);
            }
            else
                this.Text = "Добавление продукции"; // в слот ";

        }

        private void frmProduct_FormClosed(object sender, FormClosedEventArgs e)
        {
            conn.Close();
        }

        private void btn_cancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }


        //public int DomainID = -1;
        //public string ValueV = "", Text = "";
        // make  public int Place = -1, CompSlotID = -1, DomType = -1, ValueID = -1;
        private void btn_prem_add_Click(object sender, EventArgs e)
        {
            frmFact ff = new frmFact(conn, -1, "", SlotID, FrameID, true, false);
            if (ff.ShowDialog() == DialogResult.OK)
            {
                dgPremise.Rows.Add();
                int ind = dgPremise.Rows.Count - 1;
                dgPremise.Rows[ind].Cells[0].Value = -1;
                dgPremise.Rows[ind].Cells[1].Value = ff.Text + (ff.Negation ? " != " : " = ") + ff.ValueV;
                dgPremise.Rows[ind].Cells[2].Value = ff.CompSlotID;
                dgPremise.Rows[ind].Cells[3].Value = ff.Place;
                dgPremise.Rows[ind].Cells[4].Value = ff.ValueV;
                dgPremise.Rows[ind].Cells[5].Value = ff.Negation;

            }
        }

        private void btn_prem_upd_Click(object sender, EventArgs e)
        {
            if (dgPremise.SelectedCells != null && dgPremise.SelectedCells.Count > 0)
            {
                if (dgPremise.SelectedCells[1].Value != null)
                {
                    string fact_str = dgPremise.SelectedCells[1].Value.ToString();
                    frmFact ff = new frmFact(conn, (int)dgPremise.SelectedCells[0].Value, fact_str, SlotID, FrameID, true, true);
                    if (ff.ShowDialog() == DialogResult.OK)
                    {
                        int ind = dgPremise.SelectedRows[0].Index;
                        dgPremise.Rows.Remove(dgPremise.SelectedRows[0]);
                        dgPremise.Rows.Insert(ind);
                        dgPremise.Rows[ind].Cells[0].Value = -1;
                        dgPremise.Rows[ind].Cells[1].Value = ff.Text + (ff.Negation ? " != " : " = ") + ff.ValueV;
                        dgPremise.Rows[ind].Cells[2].Value = ff.CompSlotID;
                        dgPremise.Rows[ind].Cells[3].Value = ff.Place;
                        dgPremise.Rows[ind].Cells[4].Value = ff.ValueV;
                        dgPremise.Rows[ind].Cells[5].Value = ff.Negation;
                    }
                }
            }
        }

        private void DeleteProd()
        {
            int success = 0;
            var facts = Tale.Fact.Where(v => v.SlotID == SlotID);
            List<Fact> real_facts = new List<Fact>();
            foreach (Fact fct in facts)
            {
                if (Tale.ProductionFact.Where(v => v.FactID == fct.ID && v.ProductionID == ProdID).Count() > 0)
                    real_facts.Add(fct);
            }
            //var facts = facts.Where(v=>v.ProductionFact) Tale.ProductionFact.Where(v=>v.ProductionID == ProdID);
            foreach (Fact fct in real_facts)
            {
                try
                {
                    var prod_fact = Tale.ProductionFact.Where(v => v.FactID == fct.ID).First();
                    Tale.ProductionFact.DeleteObject(prod_fact);
                    Tale.SaveChanges();
                }
                catch { success = -1; }
            }
            foreach (Fact fct in real_facts)
            {
                try
                {
                    Tale.Fact.DeleteObject(fct);
                    Tale.SaveChanges();
                }
                catch { success = -1; }
            }
        }

        private bool IsUsed()
        {
            bool result = false;
            for (int i = 0; i < dgPremise.Rows.Count; i++)
            {
                if ((int)dgPremise.Rows[i].Cells[2].Value == SlotID)
                    result = true;
            }
            return result;
        }

        private void btn_OK_Click(object sender, EventArgs e)
        {
            // load to database 
            if (dgConc.Rows.Count >0 && dgPremise.Rows.Count >0 && IsUsed())
            {
                string str = "В посылке продукции не может использоваться текущий слот!";
                MessageBox.Show(str, "Ошибка", MessageBoxButtons.OK);                
            }
            else
            {
                int success = 0;
                if (IfEdit)
                {
                    DeleteProd();
                }
                // create product
                //            dgPremise.Rows[ind].Cells[1].Value = ff.Text;
                //dgPremise.Rows[ind].Cells[2].Value = ff.CompSlotID;
                //dgPremise.Rows[ind].Cells[3].Value = ff.Place;
                //dgPremise.Rows[ind].Cells[4].Value = ff.ValueV;
                var prods = Tale.ProductionFact.Where(v => v.Fact.SlotID == SlotID);
                ProductionFact prod_facct = new ProductionFact();
                int prod_id = -1, prod_number = -1;
                if (prods.Count() == 0)
                {
                    prod_id = 0;
                    prod_number = 0;
                }
                else
                {
                    prod_id = (int)prods.Max(v => v.ProductionID) + 1;
                    prod_number = (int)prods.Max(v => v.Number) + 1;
                }
                for (int i = 0; i < dgPremise.Rows.Count; i++)
                {
                    Fact new_fact = new Fact();
                    new_fact.SlotID = SlotID;
                    new_fact.CompSlotID = (int)dgPremise.Rows[i].Cells[2].Value;
                    new_fact.Place = (int)dgPremise.Rows[i].Cells[3].Value;
                    new_fact.Negation = (bool)dgPremise.Rows[i].Cells[5].Value;
                    int value_id = -1;
                    int comp_slot_id = (int)dgPremise.Rows[i].Cells[2].Value;
                    Slot slot = Tale.Slot.Where(v => v.ID == comp_slot_id).First();
                    if (slot.DomainType == null || slot.DomainType == 0)
                    {
                        string valuev = dgPremise.Rows[i].Cells[4].Value.ToString();
                        var doms = from dom in Tale.Domains
                                   join domval in Tale.DomainsValues on dom.ID equals domval.DomID
                                   join dv in Tale.DValues on domval.Value equals dv.ID
                                   where dom.Name == slot.Domains.Name && dv.Value == valuev
                                   select dv;
                        value_id = doms.First().ID;
                    }
                    else if (slot.DomainType != null && slot.DomainType > 0)
                    {
                        value_id = (int)slot.DomainType;
                    }
                    new_fact.ValueID = value_id;
                    Tale.Fact.AddObject(new_fact);
                    Tale.SaveChanges();
                    ProductionFact prod_fact = new ProductionFact();
                    prod_fact.FactID = new_fact.ID;
                    prod_fact.Number = prod_number;
                    prod_fact.ProductionID = prod_id;
                    prod_fact.Type = 1;
                    Tale.ProductionFact.AddObject(prod_fact);
                    Tale.SaveChanges();
                }
                // --------------------------------------------------------------
                prods = Tale.ProductionFact.Where(v => v.Fact.SlotID == SlotID);
                prod_facct = new ProductionFact();
                //prod_id = -1; prod_number = -1;
                //if (prods.Count() == 0)
                //{
                //    prod_id = 0;
                //    prod_number = 0;
                //}
                //else
                //{
                //    prod_id = (int)prods.Max(v => v.ProductionID) + 1;
                //    prod_number = (int)prods.Max(v => v.Number) + 1;
                //}
                for (int j = 0; j < dgConc.Rows.Count; j++)
                {
                    Fact c_new_fact = new Fact();
                    c_new_fact.SlotID = SlotID;
                    c_new_fact.CompSlotID = (int)dgConc.Rows[j].Cells[2].Value;
                    c_new_fact.Place = (int)dgConc.Rows[j].Cells[3].Value;
                    c_new_fact.Negation = (bool)dgConc.Rows[j].Cells[5].Value;
                    int c_value_id = -1;
                    int c_comp_slot_id = (int)dgConc.Rows[j].Cells[2].Value;
                    Slot c_slot = Tale.Slot.Where(v => v.ID == c_comp_slot_id).First();
                    if (c_slot.DomainType == null || c_slot.DomainType == 0)
                    {
                        string valuev = dgConc.Rows[j].Cells[4].Value.ToString();
                        var doms = from dom in Tale.Domains
                                   join domval in Tale.DomainsValues on dom.ID equals domval.DomID
                                   join dv in Tale.DValues on domval.Value equals dv.ID
                                   where dom.Name == c_slot.Domains.Name && dv.Value == valuev
                                   select dv;
                        c_value_id = doms.First().ID;
                    }
                    else if (c_slot.DomainType != null && c_slot.DomainType > 0)
                    {
                        c_value_id = (int)c_slot.DomainType;
                    }
                    c_new_fact.ValueID = c_value_id;
                    Tale.Fact.AddObject(c_new_fact);
                    Tale.SaveChanges();
                    ProductionFact c_prod_fact = new ProductionFact();
                    c_prod_fact.FactID = c_new_fact.ID;
                    c_prod_fact.Number = prod_number;
                    c_prod_fact.ProductionID = prod_id;
                    if (dgPremise.Rows.Count > 0)
                        c_prod_fact.Type = 2;
                    else
                        c_prod_fact.Type = 3;
                    Tale.ProductionFact.AddObject(c_prod_fact);
                    Tale.SaveChanges();
                }
                this.DialogResult = DialogResult.OK;
                this.Close();
            }
        }

        private void button4_Click(object sender, EventArgs e)
        {
            frmFact ff = new frmFact(conn, -1, "", SlotID, FrameID, true, false);
            if (ff.ShowDialog() == DialogResult.OK)
            {
                dgConc.Rows.Add();
                int ind = dgConc.Rows.Count - 1;
                dgConc.Rows[ind].Cells[0].Value = -1;
                dgConc.Rows[ind].Cells[1].Value = ff.Text + " = " + ff.ValueV;
                dgConc.Rows[ind].Cells[2].Value = ff.CompSlotID;
                dgConc.Rows[ind].Cells[3].Value = ff.Place;
                dgConc.Rows[ind].Cells[4].Value = ff.ValueV;
                dgConc.Rows[ind].Cells[5].Value = false; //ff.Negation;
            }
        }

        // upd conc
        private void button5_Click(object sender, EventArgs e)
        {
            if (dgConc.SelectedCells != null && dgConc.SelectedCells.Count > 0)
            {
                if (dgConc.SelectedCells[1].Value != null)
                {
                    string fact_str = dgConc.SelectedCells[1].Value.ToString();
                    frmFact ff = new frmFact(conn, (int)dgConc.SelectedCells[0].Value, fact_str, SlotID, FrameID, true, true);
                    if (ff.ShowDialog() == DialogResult.OK)
                    {
                        int ind = dgConc.SelectedRows[0].Index;
                        dgConc.Rows.Remove(dgConc.SelectedRows[0]);
                        dgConc.Rows.Insert(ind);
                        dgConc.Rows[ind].Cells[0].Value = -1;
                        dgConc.Rows[ind].Cells[1].Value = ff.Text + " = " + ff.ValueV;
                        dgConc.Rows[ind].Cells[2].Value = ff.CompSlotID;
                        dgConc.Rows[ind].Cells[3].Value = ff.Place;
                        dgConc.Rows[ind].Cells[4].Value = ff.ValueV;
                        dgConc.Rows[ind].Cells[5].Value = false; //ff.Negation;
                    }
                }
            }
        }

        private void btn_prem_del_Click(object sender, EventArgs e)
        {
            if (dgPremise.SelectedCells != null && dgPremise.SelectedCells.Count > 0)
            {
                if (dgPremise.SelectedCells[1].Value != null)
                {
                    string str = "Вы действительно хотите удалить факт?";
                    DialogResult dr = MessageBox.Show(str, "Внимание", MessageBoxButtons.OKCancel);
                    if (dr == DialogResult.OK)
                        dgPremise.Rows.Remove(dgPremise.SelectedRows[0]);
                }
            }
        }

        private void dgPremise_SelectionChanged(object sender, EventArgs e)
        {
            if (dgPremise.SelectedCells != null && dgPremise.SelectedCells.Count > 0)
            {
                if (dgPremise.SelectedCells[1].Value != null)
                {
                    btn_prem_del.Enabled = true;
                }
            }
        }

        private void dgConc_SelectionChanged(object sender, EventArgs e)
        {
            if (dgConc.SelectedCells != null && dgConc.SelectedCells.Count > 0)
            {
                if (dgConc.SelectedCells[1].Value != null)
                {
                    btn_conc_del.Enabled = true;
                }
            }
        }

        private void btn_conc_del_Click(object sender, EventArgs e)
        {
            if (dgConc.SelectedCells != null && dgConc.SelectedCells.Count > 0)
            {
                if (dgConc.SelectedCells[1].Value != null)
                {
                    string str = "Вы действительно хотите удалить факт?";
                    DialogResult dr = MessageBox.Show(str, "Внимание", MessageBoxButtons.OKCancel);
                    if (dr == DialogResult.OK)
                        dgConc.Rows.Remove(dgConc.SelectedRows[0]);
                }
            }
        }

     
    }
}
